package com.kaguya.vams.security.filter;

import cn.hutool.core.util.StrUtil;
import com.kaguya.vams.domain.entity.SysUser;
import com.kaguya.vams.security.UserDetailsServiceImpl;
import com.kaguya.vams.service.SysUserService;
import com.kaguya.vams.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.stereotype.Component;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.TreeSet;

/**
 * jwt校验过滤器 获取请求头判断是否携带jwt 如果携带 免登录
 *
 * @author : kaguya
 * @date : 0:58 2021/8/1
 */
@Slf4j
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

        log.info("jwt 校验 过滤器");
        //获取请求头
        String jwt = request.getHeader(jwtUtils.getHeader());

        //如果没有jwt 执行下一个过滤器
        if (!StrUtil.isBlankOrUndefined(jwt)) {

            //解析jwt
            Claims claimByToken = jwtUtils.getClaimByToken(jwt);

            //异常处理
            if (null == claimByToken) {
                throw new JwtException("token异常！");
            }

            if (jwtUtils.isTokenExpired(claimByToken)) {
                throw new JwtException("token已过期！");
            }

            //如果有jwt并合法，通过获取载荷中存储的username自动登录
            String username = claimByToken.getSubject();

            //根据用户名查询到用户信息，并获取权限集合
            SysUser user = sysUserService.getUserByUserName(username);

            if(null != user ) {

                //获取用户权限集合
                List<GrantedAuthority> authorityList = userDetailsService.getUserAuthorities(user.getId());

                log.info("用户-" + username + "，正在登陆！");
                //获取到用户名并封装成UsernamePasswordAuthenticationToken
                UsernamePasswordAuthenticationToken token =
                        new UsernamePasswordAuthenticationToken(username, null, authorityList);
                //设置token
                SecurityContextHolder.getContext().setAuthentication(token);
            } else {
                throw new JwtException("token非法！");
            }

        }
        //doFilter 执行下一个过滤器
        chain.doFilter(request, response);
    }
}
